<template>
    <div>
      <p><a href="https://blog.csdn.net/qq_62809806/article/details/131029895" target="_blank">滑块文章地址</a></p>
    </div>
    <div class="drag-verify">
        <div :class="['range', verifyResult ? 'success' : '']" :style="styleObj">
            <div :class="['block', verifyResult?'right': 'left']" @mousedown="onStart" @touchstart="onStart">
              <div class="icon" :style="{width:`${iconWidth}px`}">
                <CheckOutlined v-if="verifyResult" style="color: #52c41a;font-size: 30px;"/>
                <RightOutlined v-else style="color: #fff;font-size: 30px;"/>
              </div>
            </div>
            <span class="text" v-if="isTextShow">
                  {{ verifyResult ? successText : startText }}
            </span>
        </div>
        <a-button  class="margin-top20" type="primary" @click="handleClick">点我刷新</a-button>
    </div>
</template>
<script setup>
import { reactive, ref } from 'vue'
import { CheckOutlined, RightOutlined} from '@ant-design/icons-vue';


const emit = defineEmits(['update'])
const props = defineProps({
    // 整个滑块的长度
    slideWidth: {
      type: Number,
      default: 460
    },
    // 整个滑块的高度
    slideHeight: {
      type: Number,
      default: 80
    },
    // 滑动图标宽度
    iconWidth: {
      type: Number,
      default: 80
    },
    value: {
        type: Boolean,
        defalut: false
    },
    // 成功图标
    successIcon: {
        type: String,
        default: 'iconfont icon-status-nor'
    },
    // 成功文字
    successText: {
        type: String,
        default: '验证成功'
    },
    // 开始的图标
    startIcon: {
        type: String,
        default: 'iconfont icon-login-slid'
    },
    // 开始的文字
    startText: {
        type: String,
        default: '拖动滑块到最右边'
    }
})
const {slideWidth, slideHeight,iconWidth} = props

const styleObj = reactive({
  width: `${slideWidth}px`,
  height: `${slideHeight}px`,
})
const isTextShow = ref(true) //文字显隐
const verifyResult = ref(false) // 验证结果
const isTouch = 'ontouchstart' in document.documentElement
const moveEvent = isTouch ? 'touchmove' : 'mousemove'
const upEvent = isTouch ? 'touchend' : 'mouseup'

// 滑块触摸开始
/* (ev: MouseEvent | TouchEvent) */
const onStart = (ev) => {
  let disX = 0 // 滑块移动距离
  // const iconWidth = 80 // 滑动图标宽度
  // const ele = document.querySelector('.drag-verify .block') as HTMLElement
  /* (ev as MouseEvent).clientX || (ev as TouchEvent).touches[0].pageX */
  const ele = document.querySelector('.drag-verify .block')


  if(!ev) {
    // 刷新，所有重置
    ele.style.transition = '.1s all'
    ele.style.transform = `translateX(${disX}px)`
    return
  }

  const startX = ev.clientX || ev.touches[0].pageX
  // const parentWidth = ele.offsetWidth
  // const MaxX = parentWidth - iconWidth
  const MaxX = slideWidth - iconWidth

  if (verifyResult.value) {
      return false
  }

  // 滑块触摸移动
  const onMove = (e) => {
      const endX = e.clientX || e.touches[0].pageX
      isTextShow.value = false

      disX = endX - startX
      if (disX <= 0) {
          disX = 0
      }
      if (disX >= MaxX) {
          disX = MaxX
      }
      ele.style.transition = '.1s all'
      ele.style.transform = `translateX(${disX}px)`
  }

  // 滑块触摸结束
  const onEnd = () => {
    setTimeout(()=> {
      isTextShow.value = true
    },150)
    if (disX !== MaxX) {
        ele.style.transition = '.5s all'
        ele.style.transform = 'translateX(0)'
    } else {
        // 执行成功
        verifyResult.value = true
        console.log("执行成功");
        // emit('update', verifyResult.value)
    }

    document.removeEventListener(moveEvent, onMove)
    document.removeEventListener(upEvent, onEnd)
  }
  document.addEventListener(moveEvent, onMove)
  document.addEventListener(upEvent, onEnd)
}
const handleClick = ()=> {
  verifyResult.value = false
  onStart()
}
</script>
<style lang="less" scoped>
.drag-verify {
    .range {
        // height: 80px;
        // width: 460px;
        background-color: #ececee;
        position: relative;
        border-radius: 4px;
        transition: 1s all;
        user-select: none;
        color: #666;
        overflow: hidden;
        display: flex;
        justify-content: center;
        align-items: center;
        // height: 40px;
        &.success {
            background-color: #03c5e5;
            color: #fff;
            .text {
                position: relative;
                z-index: 1;
            }
            .block i {
                color: #838cfc;
            }
        }
        .block {
            display: block;
            position: absolute;
            // left: calc(-100% + 80px);
            // width: 100%;
            // width: 80px;
            left: 0;
            height: 100%;
            // background: pink;
            background: #838cfc;
            border-radius: 4px;
            overflow: hidden;
            i {
                position: absolute;
                right: 0;
                width: 40px;
                height: 100%;
                font-size: 20px;
                color: #c8c9cc;
                background-color: #fff;
                border: 1px solid #e5e5e5;
                border-radius: 4px;
                cursor: pointer;
                display: flex;
                justify-content: center;
                align-items: center;
            }
        }
    }
}
.icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background: #838cfc;
  // width: 80px;
  height: 100%;
}
.left {
  align-items: flex-end
}
.right {
  align-items: flex-start
}
</style>

